<template>
  <div class="wrap">
    <template>
      <div class="d-flex align-items-center">
        <query-list
          v-model="params.pointCloudList"
          :description="$t('message.PointCloud.selectPointCloud')"
          :tipMsg="$t('message.PointCloud.selectPointCloud')"
          @removeItem="removeSelect">
        </query-list>
      </div>
      <div class="d-flex align-items-center">
        <label class="el-form-item__label">{{$t('message.PointCloud.meshing.distance')}}:</label>
        <el-input v-model="params.deviationDistance.variableValue"
                  :min="params.boundary.deviationDistance.min"
                  :max="params.boundary.deviationDistance.max"
                  :step="0.1"
                  type="number"
                  @change="changeDistance"/>
        <label class="el-form-item__label">mm</label>
      </div>
      <div class="d-flex align-items-center">
        <el-label><b>{{ $t('message.PointCloud.meshing.smooth') }}</b></el-label>
      </div>
      <div class="smoothRange center">
        <input type="range"
               v-model="params.smoothness"
               :min="params.smoothRange.min"
               :max="params.smoothRange.max"
               :step="params.smoothRange.step"
               @change="changeSmooth"/>
      </div>
      <div class="dialog-row mt-3">
        <el-checkbox v-model="params.remind"
                         :label="$t('message.PointCloud.meshing.remind')"/>
      </div>

      <div class="el-dialog--center mt-3">
        <el-button id="buttonCalculate"
                   size="small"
                   type="calculate"
                   :disabled="!allowPreview"
                   @click="calculate"
                   :loading="params.calculating">
          <slot v-if="params.calculating" name="calculating">{{ $t('message.PointCloud.calculating') }}
          </slot>
          <slot v-else name="calculate">{{ $t('message.PointCloud.calculate') }}</slot>
        </el-button>
        <el-button id="butonReset"
                   size="small"
                   type="info"
                   :disabled="!allowReset"
                   @click="reset">
          <slot name="calculating">{{ $t('message.PointCloud.reset') }}
          </slot>
        </el-button>
      </div>

      <div class="collapse-panel">
        <div class="collapse-a">
          <div>
            <p><b>{{ $t('message.PointCloud.meshing.detail') }}</b></p>
          </div>
          <div :id="collapseId" @click="foldClick">
                    <span class="cursor-pointer" :class="[{'cursor-pointer': !disabled}]">
                        <i :class="['fa', collapse ? 'fa-angle-up' : 'fa-angle-down']"/>
                    </span>
          </div>
        </div>
        <div v-show="!collapse">
          <div class="detail">
            <p style="margin-bottom: 10px">{{ $t('message.PointCloud.meshing.pointCloudPoints') }}：{{ reconstructionDetail.pointNum }}</p>
            <p v-if="reconstructionDetail.triangleNum > 0"
               style="margin-bottom: 10px">
              {{ $t('message.PointCloud.meshing.triangleNums') }}：{{ reconstructionDetail.triangleNum }}
            </p>
          </div>
        </div>
      </div>
    </template>
    <template>
      <div class="dialog-footer pt-1 pb-2 pl-2 pr-2">
        <el-button id="buttonApply"
                   ref="applyButton"
                   type="primary"
                   class="dialog-footer__apply-button"
                   :disabled="!allowConfirm"
                   @click="applyCmd"
                   @keyup.enter.native="applyCmd">
          {{ $t('message.PointCloud.apply') }}
        </el-button>
        <el-button id="buttonConfirm"
                   ref="confirmButton"
                   type="primary"
                   class="dialog-footer__confirm-button"
                   :disabled="!allowConfirm"
                   @click="confirmCmd"
                   @keyup.enter.native="confirmCmd">
          {{ $t('message.PointCloud.confirm') }}
        </el-button>
        <el-button id="buttonClose"
                   ref="closeButton"
                   class="dialog-footer__close-button"
                   :disabled="false"
                   @click="closeCmd"
                   @keyup.enter.native="closeCmd">
          {{ $t('message.PointCloud.close') }}
        </el-button>
      </div>
    </template>
  </div>
</template>

<script>
import InputVariable from "../../../util/InputVariable";
import {ParamBoundary} from "../../../Command/pointCloud/ParamBoundary";
import {pointCloudReconstructionCommand} from "../../../Command/pointCloud/PointCloudReconstructionCommand";
import {BoolType, SamplingType} from "../../../Command/pointCloud/PointCloudType";
import {ElementType} from "../../../modeling/TypeDefine";

export default {
  name: "CmdDlgPointCloudReconstruction",
  data() {
    return {
      disabled: false,
      collapseId: 'dialogCollapsed',
      collapse: false,
      optionApplyOrConfirm: 'Apply',
      showConfirm: true,
      params: {
        pointCloudList: [],                // 点云列表
        deviationDistance: new InputVariable(0), // 缩减比例
        boundary:{
          deviationDistance: new ParamBoundary(0, true),  // 点间距离范围
        },
        smoothness: 0.0,     // 平滑度
	      smoothRange: {       // 平滑度范围
          min: 0,
          max: 1,
          step: 0.01,
        },
        remind: true,                     // 是否保留原始点云
        previewUUID: null,
        calculating: false,                // 是否在计算中
        isPreviewed: false,               // 是否已经预览过了
      },
      pointCloudElement: null,  // 点云元素
      reconstructionDetail: {
        pointNum: 0,
        triangleNum: 0
      },
    }
  },
  created() {
    pointCloudReconstructionCommand.init(500,250,800,() => {
      this.changePluginContainerHeight(100);
      this.pickFeatureNodeMode();
      this.pickElementMode();
    });
  },
  beforeDestroy() {
    this.clearPreview();
    pointCloudReconstructionCommand.closeActiveCmd();
  },
  methods: {
    pickFeatureNodeMode() {
      let filterSelectTypes = [ElementType.POINTCLOUD];
      pointCloudReconstructionCommand.setSelectType(filterSelectTypes);
      pointCloudReconstructionCommand.handlePickFeatureNode(res => {
        if(res?.feature?.type.includes('PointCloud')) {
          let type = res?.feature?.type;
          let name = res?.feature?.name;
          if (type.includes('PointCloud') && !type.includes('Reconstruction')) {
            if (this.params.pointCloudList.length > 0) {
              this.params.pointCloudList.length = 0;
            }
            pointCloudReconstructionCommand.getElementsByFeatureNames([name], elements => {
              if(elements?.data?.elements[0]?.id) {
                console.log('PointCloud Elements: ' + elements);
                this.params.pointCloudList.push(res.feature);
                let element = elements.data.elements[0];
                this.pointCloudElement = element;
                this.initParams();
              } else {
                let element = this.pointCloudElement;
                pointCloudReconstructionCommand.clearAllHighLight();
                pointCloudReconstructionCommand.highLightElements([element.id]);
              }
            });
          } else if(this.params.pointCloudList.length > 0 && this.pointCloudElement) {
            let element = this.pointCloudElement;
            pointCloudReconstructionCommand.clearAllHighLight();
            pointCloudReconstructionCommand.highLightElements([element.id]);
          } else {
            pointCloudReconstructionCommand.clearAllHighLight();
          }
        } else if(this.params.pointCloudList.length > 0 && this.pointCloudElement) {
          let element = this.pointCloudElement;
          pointCloudReconstructionCommand.clearAllHighLight();
          pointCloudReconstructionCommand.highLightElements([element.id]);
        }
      });
    },
    pickElementMode() {
      let filterSelectTypes = [ElementType.POINTCLOUD];
      pointCloudReconstructionCommand.setSelectType(filterSelectTypes);
      pointCloudReconstructionCommand.handlePickElement(res => {
        if(res?.element[0]?.element) {
          let element = res?.element[0]?.element
          this.pointCloudElement = element;
          let name = element.name;
          let featureName = name.slice(0, name.indexOf(this.$t('message.PointCloud.elementName')));
          pointCloudReconstructionCommand.getFeaturesByNames([featureName], result => {
            if(result?.data?.features[0]?.id) {
              let feature = result?.data?.features[0];
              if (this.params.pointCloudList.length > 0) {
                this.params.pointCloudList.length = 0;
              }
              this.params.pointCloudList.push(feature);
              this.initParams();
            }
          });
        } else if(this.params.pointCloudList.length > 0 && this.pointCloudElement) {
          let element = this.pointCloudElement;
          pointCloudReconstructionCommand.clearAllHighLight();
          pointCloudReconstructionCommand.highLightElements([element.id]);
        }
      });
    },
    //拾取后参数初始化
    initParams() {
      if(this.checkParam()){
        this.getNeighborDistance();
      }
      if (this.params.pointCloudList.length > 0) {
        let pointCloud = this.pointCloudElement;
        this.reconstructionDetail.pointNum = pointCloud.params.curPointNum;
      } else {
        this.reconstructionDetail.pointNum = 0;
      }
    },
    //计算点间距离
    getNeighborDistance(){
      let pointCloud = this.pointCloudElement;
      let config = pointCloud.id;
      pointCloudReconstructionCommand.getNeighborDistance(config, res => {
        if(res) {
          this.params.boundary.deviationDistance.min = res.min;
          this.params.boundary.deviationDistance.max = res.max;
          this.params.deviationDistance.variableValue = parseFloat(res.variableValue).toFixed(2);
        }
      });
    },
	  //改变平滑度
    changeSmooth() {
      this.reset();
    },
    //计算按钮
    calculate() {
      this.params.calculating = true;
      this.preview();
    },
    //预览
    preview() {
      if(!this.checkParam()){
        return;
      }
      let config = this.getCommandParams();
      pointCloudReconstructionCommand.previewPointCloudReconstruction(config,res => {
        if(res) {
          this.params.isPreviewed = true;
          this.params.calculating = false;
          this.reconstructionDetail.triangleNum = res;
        }
      });
    },
    // 改变点间距离
    changeDistance(value) {
      if(this.params.deviationDistance.variableValue < this.params.boundary.deviationDistance.min ) {
        this.params.deviationDistance.variableValue = this.params.boundary.deviationDistance.min;
      }else if(this.params.deviationDistance.variableValue > this.params.boundary.deviationDistance.max ) {
        this.params.deviationDistance.variableValue = this.params.boundary.deviationDistance.max;
      }
      if (this.params.pointCloudList.length < 1 || !value) {
        return;
      }
      this.reset();
    },
    //重置
    reset() {
      this.clearPreview();
      this.params.isPreviewed = false;
      this.reconstructionDetail.triangleNum = 0;
    },
    //清除预览
    clearPreview() {
      pointCloudReconstructionCommand.clearPreview();
    },
    //应用
    applyCmd() {
      this.optionApplyOrConfirm = 'Apply';
      this.confirm();
    },
    //确定
    confirmCmd() {
      this.optionApplyOrConfirm = 'Confirm';
      this.confirm();
    },
    //确定和应用
    confirm() {
      if(!this.checkParam()){
        return;
      }
      let config = this.getCommandParams();
      pointCloudReconstructionCommand.createPointCloudReconstruction(config,() => {
        this.params.calculating = false;
        this.params.isPreviewed = false;
        this.resetParams();
        pointCloudReconstructionCommand.clearPreview();
        if(this.optionApplyOrConfirm === 'Confirm') {
          pointCloudReconstructionCommand.closeActiveCmd();
        }
      });
    },
    //获取发送命令的参数
    getCommandParams() {
      let pointCloudTopoId = this.pointCloudElement.params.entityRefTopoId;
      let distance = new InputVariable(parseFloat(this.params.deviationDistance.variableValue));
      let smoothness = new InputVariable(this.params.smoothness);
      let remind = this.params.remind ? BoolType.TRUE : BoolType.FALSE;

      return {
        pointCloudId: pointCloudTopoId,
        distance: distance,
        smoothness: smoothness,
        remind: remind,
      };
    },
    removeSelect(){
      pointCloudReconstructionCommand.clearAllHighLight();
      this.params.isPreviewed = false;
    },
    //安全检查
    checkParam() {
      if (this.params.pointCloudList.length < 1) {
        return false;
      }
      return true;
    },
    //关闭
    closeCmd() {
      this.clearPreview();
      pointCloudReconstructionCommand.closeActiveCmd();
    },
    resetParams() {
      this.params.pointCloudList = [];
      this.pointCloudElement = null;
    },
    //控制折叠展开
    foldClick() {
      if (this.disabled) {
        return;
      }
      this.collapse = !this.collapse;
    },
    changePluginContainerHeight(height) {
      pointCloudReconstructionCommand.changePluginContainerHeight(
        {minWidth: this.$el.clientWidth, maxHeight: 280 + height})
    },
    changeContainerHeight() {
      let height = 0;
      if(this.params.pointCloudList.length < 1) {
        height += 0;
      } else {
        height += 1;
      }
      if(this.collapse) {
        height += 0;
      } else {
        height += 100;
      }
      this.changePluginContainerHeight(height);
    },
  },
  computed: {
    allowPreview() {
      return !this.params.calculating
        && this.params.pointCloudList.length > 0
        && this.params.deviationDistance
        && !this.allowReset;
    },
    allowConfirm() {
      return !this.params.calculating
        && this.params.pointCloudList.length > 0
        && (this.params.deviationDistance || this.params.isPreviewed);
    },
    allowReset() {
      return this.params.isPreviewed;
    }
  },
  watch: {
    'params.pointCloudList': {
      handler(newVal, oldVal) {
        this.changeContainerHeight();
      },
    },
    'collapse': {
      handler(newVal, oldVal) {
        this.changeContainerHeight();
      },
    },
  }
}

</script>

<style scoped>

.wrap {
    font-size: 12px;
}

.dialog-row {
    display: flex;
}

.center {
    display: flex;
    justify-content: center;
}

.smoothRange {
    margin-top: 10px;
}

.smoothRange input[type=range] {
    -webkit-appearance: none;
    height: 6px;
    width: 90%;
    border: 0px;
    background: var(--bg-color8);
    outline: none;
}

.smoothRange input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    height: 20px;
    width: 10px;
    background: var(--bg-color7);
    /*border-radius: 50% 50% 0 0;*/
    border: solid 1px rgba(0, 0, 0, 0.3);
    z-index: 1;
}

.smoothRange input[type=range]:hover {
    cursor: pointer;
}

.detail {
    width: 100%;
    font-size: 13px;
    height: 100px;
    background-color: #eae8e8;
    overflow-y: auto;
    padding: 5px;
}

.collapse-panel > .collapse-a {
    color: var(--text-color1);
    margin: 5px 0;
}

.collapse-a {
    display: flex;
    justify-content: space-between;
}

.detail {
    width: 100%;
    font-size: 13px;
    max-height: 10em;
    background-color: #eae8e8;
    overflow-y: auto;
    padding: 5px;
}

.el-button--calculate:focus,
.el-button--calculate:hover {
    background: #1777f5 !important;   /* 背景颜色*/
    color: #ffffff !important;        /* 字体颜色*/
    border-color: #9b9a9a !important; /* 边界颜色*/
}

.el-button--calculate.is-disabled,
.el-button--calculate.is-disabled:hover {
    background: #92c2f3 !important;   /* 背景颜色*/
    color: #ffffff !important;        /* 字体颜色*/
    border-color: #9b9a9a !important; /* 边界颜色*/
}

.el-button--calculate {
    background: #3c8cf5 !important;   /* 背景颜色*/
    color: #ffffff !important;        /* 字体颜色*/
    border-color: #9b9a9a !important; /* 边界颜色*/
}

.dialog-footer {
    display: flex;
    justify-content: flex-end;
}

.dialog-footer >>> .el-button {
    font-size: 12px;
}

</style>
